// File: src/core/tasks/TaskManager.cpp
#include "core/tasks/TaskManager.h"
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>

bool TaskManager::addTask(Task& task) {
    std::lock_guard<std::mutex> lock(tasksMutex);// 进入方法时加锁
    // 加锁后作用域内均变为临界区代码
    // 离开作用域时自动解锁
    if (taskExists(task.getName(), task.getStartTime())) {
        std::cerr << "任务已存在: " << task.getName() 
                  << " at " << task.getFormattedStartTime() << std::endl;
        return false;
    }
    
    //task.setId(getNextId()); // 使用安全的ID分配方法
    tasks.push_back(task);
    std::cout << "任务添加成功: " << task.getName() << " (ID: " << task.getId() << ")" << std::endl;
    return true;
}

bool TaskManager::removeTask(int taskId) {
    std::lock_guard<std::mutex> lock(tasksMutex);
    
    auto it = std::remove_if(tasks.begin(), tasks.end(),
        [taskId](const Task& t) { return t.getId() == taskId; });
    // std::remove_if： 遍历 tasks 容器，查找所有 Task 对象，检查其 id 是否等于传入的 taskId。
    // 如果找到匹配的任务，它会把这些任务移动到容器的末尾，并返回一个迭代器 it，指向第一个被移动的元素。
    // Lambda 表达式：[taskId](const Task& t) { return t.getId() == taskId; } 是一个Predicate，用于判断任务的 id 是否匹配
    if (it != tasks.end()) {
        tasks.erase(it, tasks.end());
        std::cout << "任务删除成功: ID " << taskId << std::endl;
        return true;
    }
    
    std::cerr << "任务未找到: ID " << taskId << std::endl;
    return false;
}

std::vector<Task> TaskManager::getTasksForDay(std::time_t day) const {
    std::lock_guard<std::mutex> lock(tasksMutex);// 进入方法时加锁
    std::vector<Task> result;
    
    std::time_t startOfDay = getStartOfDay(day);
    std::time_t endOfDay = startOfDay + 24 * 60 * 60;
    
    for (const auto& task : tasks) {
        if (task.getStartTime() >= startOfDay && task.getStartTime() < endOfDay) {
            result.push_back(task);
        }
    }
    std::tm* tm = std::localtime(&day);
    int targetYear = tm->tm_year;
    int targetMonth = tm->tm_mon;
    int targetDay = tm->tm_mday;
    std::cout << "查询日期: UTC " << targetYear+1900 << "-" << targetMonth+1 << "-"
        << targetDay << "\n";
    // 按照起始时间排序
    std::sort(result.begin(), result.end(), [](const Task& a, const Task& b) {
        return a.getStartTime() < b.getStartTime();
    });
    
    return result;
}

std::vector<Task> TaskManager::getTasksForMonth(std::time_t month) const{
    std::lock_guard<std::mutex> lock(tasksMutex); // 进入方法时加锁
    std::vector<Task> result;
    
    // 获取传入时间的年月（忽略日时分秒）
    std::tm* tm = std::localtime(&month);
    int targetYear = tm->tm_year;
    int targetMonth = tm->tm_mon;
    for (const auto& task : tasks) {
        std::time_t taskTime = task.getStartTime();
        std::tm* taskTm = std::localtime(&taskTime);
        
        // 比较年月是否匹配
        if (taskTm->tm_year == targetYear && 
            taskTm->tm_mon == targetMonth) {
            result.push_back(task);
        }
    }
    std::cout << "查询月份: UTC " << targetYear+1900 << "-" << targetMonth+1  
          << "\n";
    // 按开始时间排序
    std::sort(result.begin(), result.end(), [](const Task& a, const Task& b) {
        return a.getStartTime() < b.getStartTime();
    });
    
    return result;
}

void TaskManager::checkReminders() {
    std::lock_guard<std::mutex> lock(tasksMutex);// 进入方法时加锁
    std::time_t now = std::time(nullptr);
    
    for (auto& task : tasks) {
        if (task.shouldRemind(now)) {
            std::string message = "\n[提醒] " + task.getName() + 
                                 " 将在 " + task.getFormattedStartTime() + 
                                 " 开始";
            
            // 传递优先级参数
            emit reminderTriggered(QString::fromStdString(message), 
                                  static_cast<int>(task.getPriority()));
            
            task.markReminded();
        }
    }

}

void TaskManager::saveTasks(const std::string& username) {
    std::lock_guard<std::mutex> lock(tasksMutex);// 进入方法时加锁
    std::ofstream file(username + "_tasks.tmdb");
    
    if (!file) {
        std::cerr << "无法打开任务文件保存" << std::endl;
        return;
    }
    
    file << "id|name|start_timestamp|priority|category|remind_timestamp|reminded\n";
    
    for (const auto& task : tasks) {
        file << task.getId() << "|"
             << task.getName() << "|"
             << task.getStartTime() << "|"
             << static_cast<int>(task.getPriority()) << "|"
             << static_cast<int>(task.getCategory()) << "|"
             << task.getRemindTime() << "|"
             << task.isReminded() << "\n";
    }
}

void TaskManager::loadTasks(const std::string& username, bool preserveExisting) {
    std::lock_guard<std::mutex> lock(tasksMutex);// 进入方法时加锁
    std::ifstream file(username + "_tasks.tmdb");
    
    if (!file) {
        std::cout << "没有找到任务数据，创建新文件" << std::endl;
        nextId = 1; // 重设为初始值
        return;
    }
    
    std::vector<Task> newTasks;
    int maxId = nextId - 1;
    // Skip header
    std::string line;
    std::getline(file, line);
    
    while (std::getline(file, line)) {
        std::istringstream iss(line);
        std::string token;
        std::vector<std::string> tokens;
        // 以'|'为分界标志将读如字符串拆分为日期时间、优先级等信息
        while (std::getline(iss, token, '|')) {
            tokens.push_back(token);
        }
        
        if (tokens.size() < 7) continue;
        
        try {
            int id = std::stoi(tokens[0]);
            std::string name = tokens[1];
            std::time_t startTime = std::stol(tokens[2]);
            Priority priority = static_cast<Priority>(std::stoi(tokens[3]));
            Category category = static_cast<Category>(std::stoi(tokens[4]));
            std::time_t remindTime = std::stol(tokens[5]);
            bool reminded = std::stoi(tokens[6]);
            
            Task task(name, startTime, priority, category, remindTime);
            task.setId(id); // 强制使用文件中的原始ID
            std::time_t now = std::time(nullptr);
            if(now > remindTime)
                task.markReminded(); // 构造task时reminded默认为false，需要正确恢复任务在加载前原有的提醒状态
            newTasks.push_back(task);
            maxId = std::max(maxId, id);
        } catch (...) {
            std::cerr << "解析任务数据失败: " << line << std::endl;
        }
    }
    if (preserveExisting) {
        // 合并新旧任务（以文件中的数据为准去重）
        auto oldTasks = std::move(tasks);
        tasks = std::move(newTasks);
        
        for (const auto& oldTask : oldTasks) {
            if (!taskExists(oldTask.getName(), oldTask.getStartTime())) {
                tasks.push_back(oldTask);
            }
        }
    } else {
        tasks = std::move(newTasks);
    }

    nextId = maxId + 1;
    std::cout << "加载了 " << tasks.size() << " 个任务" << std::endl;
    //std::cout << "nextId = " << nextId <<std::endl;
}


std::vector<Task> TaskManager::getAllTasks() const {
    std::lock_guard<std::mutex> lock(tasksMutex);// 进入方法时加锁
    return tasks; // 返回副本
}

std::time_t TaskManager::getStartOfDay(std::time_t time) const {
    std::tm* tm = std::localtime(&time);
    tm->tm_hour = 0;
    tm->tm_min = 0;
    tm->tm_sec = 0;
    return std::mktime(tm);
}

bool TaskManager::taskExists(const std::string& name, std::time_t startTime) const {
    /*return std::any_of(tasks.begin(), tasks.end(), [&](const Task& t) {
        return t.getName() == name && t.getStartTime() == startTime;
    });*/
    //循环版本如下：
    for (const auto& t : tasks) {
        if (t.getName() == name && t.getStartTime() == startTime) {
        return true;
        }
    }
    return false;
}

Task TaskManager::getTask(int taskId) const
{
    Task foundTask("", 0);
    auto it = std::find_if(tasks.begin(), tasks.end(),
    [taskId](const Task& t) { return t.getId() == taskId; });

    if (it != tasks.end()) 
        foundTask = *it;  // 获取匹配的 Task 对象
    return foundTask;
}